#ifndef _TWITTER_RESOURCE_TWEETS_H_
#define _TWITTER_RESOURCE_TWEETS_H_

#include "object.h"

NS_BEGIN(Twit)
NS_BEGIN(Resource)
NS_BEGIN(Tweets)

typedef TObjectStatuses<Value::Status>      OStatusesVStatus;
typedef TObjectStatuses<Value::IDs>         OStatusesVIDs;


/**
* @brief Returns a single statuses, specified by the id parameter below. 
*  The statuses's author will be returned inline.
*/
class Show:public OStatusesVStatus
{
public:
	Show(IOAuth& o):OStatusesVStatus(o,"")
	{
		std::string path = getPath();
		path += "/show";
		setPath(path.c_str());
		setConstraints(false,true);
	}

   /**
   * @param statusId The numerical ID of the desired statuses.
   */
   bool request(Value::UniqueID statusId)
   {
	   setFile(statusId.toString().c_str());
	   return OStatusesVStatus::request();
   }

   /**
   * @param statusId The numerical ID of the desired statuses.
   */
   Value::Status& get(Value::UniqueID statusId)
   {
	   setFile(statusId.toString().c_str());
	   return OStatusesVStatus::get();
   }
};

/**
* @brief 
*  Updates the authenticating user's statuses. A statuses Update with text identical 
*  to the authenticating user's text identical to the authenticating user's current statuses 
*  will be ignored to prevent duplicates.
*/
struct Update:public OStatusesVStatus
{
	Update(IOAuth& o):OStatusesVStatus(o,"update")
	{
		setRequestMethod(RequestMethodPost);
		setConstraints(true,false);
	}

   /**
   * @param status The text of your status Update, up to 140 characters. URL encode as necessary.
   */
   bool request(std::wstring status)
   {
	   setParam("status", Convert::UnicodeToUtf8(status).c_str());
	   return OStatusesVStatus::request();
   }

   bool request(std::wstring& status)
   {
	   setParam("status", Convert::UnicodeToUtf8(status).c_str());
	   return OStatusesVStatus::request();
   }

   Value::Status& get(std::wstring status)
   {
	   setParam("status", Convert::UnicodeToUtf8(status).c_str());
	   return OStatusesVStatus::get();
   }

   Value::Status& get(std::wstring& status)
   {
	   setParam("status", Convert::UnicodeToUtf8(status).c_str());
	   return OStatusesVStatus::get();
   }

   void setInReplyToStatusId(Value::UniqueID id)
   {
	   setParam("in_reply_to_status_id", id.toString().c_str());
   }

   /**
   * @param latitude
   *  The latitude of the location this tweet refers to. 
   *  This parameter will be ignored unless it is inside the range -90.0 to +90.0 (North is positive) 
   *  inclusive. 
   * @param longitude
   *  The longitude of the location this tweet refers to. 
   *  The valid ranges for longitude is -180.0 to +180.0 (East is positive) inclusive. 
   *  This parameter will be ignored if outside that range, if it is not a number, 
   *  if geo_enabled is disabled
   */
   void setLocation(double latitude, double longitude)
   {
	   char pszLat[32]={0,}, pszlong[32]={0,};
	   if(latitude==0 || longitude==0)
	   {
		   pszLat[0] = ' ';
		   pszlong[0] = ' ';
	   }
	   else
	   {
		   TwitUtil_locationValue_to_string(latitude, pszLat);
		   TwitUtil_locationValue_to_string(longitude, pszlong);
	   }
	   setLocation(std::string(pszLat), std::string(pszlong));
   }

   void setLocation(std::string latitude, std::string longitude)
   {
	   if(latitude.empty()||longitude.empty())
	   {
		   setParam("lat");
		   setParam("long");
	   }
	   else
	   {
		   setParam("lat",latitude.c_str());
		   setParam("long",longitude.c_str());
	   }
   }

   void setLocation(Value::Coordinate coord)
   {
	   if(coord.isNull())
	   {
		   setParam("lat");
		   setParam("long");
	   }
	   else
	   {
		   setParam("lat",Util::toString(coord.getLatitude()).c_str() );
		   setParam("long", Util::toString(coord.getLongtitude()).c_str() );
	   }
   }

   void setPlaceId(std::string place_id)
   {
	   setParam("place_id", place_id.c_str());
   }
   void setDisplayCoordinates(bool dc)
   {
	   setParam("display_coordinates", dc);
   }
};


/**
* @brief 
*  Destroys the statuses specified by the required ID parameter.
*  Usage note: The authenticating user must be the author of the specified statuses.
*/
class Destroy:public OStatusesVStatus
{
public:
	Destroy(IOAuth& o):OStatusesVStatus(o,"")
	{
		std::string path = getPath();
		path += "/destroy";
		setPath(path.c_str());
		setRequestMethod(RequestMethodPost);
		setConstraints(true,false);
	}

   /**
   * @param The numerical ID of the desired statuses.
   */
   bool request(Value::UniqueID statusId)
   {
	   setFile(statusId.toString().c_str());
	   return OStatusesVStatus::request();
   }

   /**
   * @param The numerical ID of the desired statuses.
   */
    Value::Status& get(Value::UniqueID statusId)
	{
		setFile(statusId.toString().c_str());
		return OStatusesVStatus::get();
	}
};


/**
* @brief Retweets a tweet. Returns the original tweet with Retweet details embedded.
*/
struct Retweet:public OStatusesVStatus
{
	Retweet(IOAuth& o):OStatusesVStatus(o,"")
	{
		std::string path = getPath();
		path += "/retweet";
		setPath(path.c_str());
		setRequestMethod(RequestMethodPost);
		setConstraints(false,false);
	}

   /**
   * @param The numerical ID of the desired statuses.
   */
   bool request(Value::UniqueID statusId)
   {
	   setFile(statusId.toString().c_str());
	   return OStatusesVStatus::request();
   }

   /**
   * @param The numerical ID of the desired statuses.
   */
   Value::Status& get(Value::UniqueID statusId)
   {
		setFile(statusId.toString().c_str());
		return OStatusesVStatus::get();
   }
};


/**
* @brief Returns up to 100 of the first Retweets of a given tweet.
*/
struct Retweets:public OStatusesVStatuses
{
	Retweets(IOAuth& o):OStatusesVStatuses(o,"")
	{
		std::string path = getPath();
		path += "/retweets";
		setPath(path.c_str());
		setConstraints(false,true);
	}

   /**
   * @brief Specifies the number of records to retrieve. Must be less than or equal to 100.
   */
   void setCount(const size_t count)
   {
	   setParam("count", (int)count);
   }

   /**
   * @param id The numerical ID of the desired statuses.
   */
   bool request(Value::UniqueID statusId)
   {
	   setFile(statusId.toString().c_str());
	   return OStatusesVStatuses::request();
   }

   /**
   * @param id The numerical ID of the desired statuses.
   */
   Value::Statuses& get(Value::UniqueID statusId)
   {
	   setFile(statusId.toString().c_str());
	   return OStatusesVStatuses::get();
   }
};

/**
* @brief Show user objects of up to 100 members who retweeted the statuses.
*/

struct RetweetedBy:public OStatusesVUsers
{
	RetweetedBy(IOAuth& o):OStatusesVUsers(o,"retweeted_by")
	{
		setConstraints(true,true);
	}

   /**
   * @param count Specifies the number of records to retrieve. Must be less than or equal to 100.
   */
   void setCount(size_t count)
   {
	   setParam("count", (int)count);
   }

   /**
   * @param page Specifies the page of results to retrieve.
   */
   void setPage(size_t page)
   {
	   setParam("page", (int)page);
   }

   /**
   * @param id The numerical ID of the desired statuses.
   */
   bool request(Value::UniqueID statusId)
   {
	   std::string path = "statuses/" + statusId.toString();
	   setPath(path.c_str());
	   return OStatusesVUsers::request();
   }

   /**
   * @param id The numerical ID of the desired statuses.
   */
   Value::Users& get(Value::UniqueID statusId)
   {
	   std::string path = "statuses/" + statusId.toString();
	   setPath(path.c_str());
	   return OStatusesVUsers::get();
   }
};

/**
* @brief Show user ids of up to 100 users who retweeted the statuses.
*/
struct RetweetedByIDs:public OStatusesVIDs
{
	RetweetedByIDs(IOAuth& o):OStatusesVIDs(o,"retweeted_by/ids")
	{
		setConstraints(true,true);
	}

   /**
   * @param count Specifies the number of records to retrieve. Must be less than or equal to 100.
   */
   void setCount(size_t count)
   {
	   setParam("count",(int)count);
   }

   /**
   * @param page Specifies the page of results to retrieve.
   */
   void setPage(size_t page)
   {
	   setParam("page",(int)page);
   }

   /**
   * @param id The numerical ID of the desired statuses.
   */
   bool request(Value::UniqueID statusId)
   {
	   std::string path = "statuses/" + statusId.toString();
	   setPath(path.c_str());
	   return OStatusesVIDs::request();
   }

   /**
   * @param id The numerical ID of the desired statuses.
   */
   Value::IDs& get(Value::UniqueID statusId)
   {
	   std::string path = "statuses/" + statusId.toString();
	   setPath(path.c_str());
	   return OStatusesVIDs::get();
   }
};

NS_END;

DeclareResourceClass(CTweets)
CTweets(IOAuth& o):Show(o), Update(o), Destroy(o), Retweet(o), Retweets(o), RetweetedBy(o),
RetweetedByIDs(o){}
public:
Tweets::Show            Show;
Tweets::Update          Update;
Tweets::Destroy         Destroy;
Tweets::Retweet         Retweet;
Tweets::Retweets        Retweets;
Tweets::RetweetedBy     RetweetedBy;
Tweets::RetweetedByIDs  RetweetedByIDs;
EndResourceClass;
   NS_END;
NS_END;

#endif /*_TWITTER_RESOURCE_TWEETS_H_*/
